import re
from typing import Dict, List, AnyStr

from pptx import Presentation
from pptx.slide import Slides
from pptx.text.text import _Paragraph
from string import Template


class PPtReplace:
    def __init__(self, filename: str):
        self.ppt = Presentation(filename)
        self._variable = []
        self._dict = {}

    def slides(self) -> Slides:
        return self.ppt.slides

    def length(self) -> int:
        return len(self.ppt.slides)

    def slide_text(self, slide) -> List[_Paragraph]:
        """
        幻灯片的文本
        """
        for shape in slide.shapes:
            if shape.has_text_frame:
                for paragraph in shape.text_frame.paragraphs:
                    for run in paragraph.runs:
                        yield run

    def _re_text(self, run) -> List[AnyStr]:
        return re.findall('\${(.*?)}', run.text, re.S)

    def get_variable(self) -> List[AnyStr]:
        """
        获取 ppt 变量
        """
        for slide in self.slides():
            for run in self.slide_text(slide):
                _re = self._re_text(run)
                if len(_re) > 0:
                    for line in _re:
                        self._variable.append(line)
        return self._variable

    def get_dict(self) -> Dict:
        """
        获取对应信息
        """
        return self._dict

    def set_dict(self, value) -> Dict:
        self._dict = value

    def set_value(self, value: list) -> Dict:
        self._dict = dict(zip(self.get_variable(), value))
        return self._dict

    def _set_text(self):
        for slide in self.slides():
            for run in self.slide_text(slide):
                run.text = Template(run.text).substitute(self._dict)

    def save(self, filename: str) -> None:
        """
        保存
        """
        self.ppt.save(filename)

    def replace_save(self, filename: str) -> None:
        self._set_text()
        self.save(filename)


if __name__ == '__main__':
    filename = r"F:\test\ppt\test.pptx"
    ppt = PPtReplace(filename)
    ppt.set_value(['text', 'Tom'])
    ppt.replace_save('./a.pptx')
